﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
#if WINDOWS
using System.Windows.Forms;
#endif

namespace Sharpie.Libs
{
    public static class Locale
    {
        public static Language currentLang;
#if ANDROID
        public readonly static string LangDir = Path.Combine(SharpieAndroid.Activity1.AppDataPath, "Lang");
#else
        public readonly static string LangDir = "Lang";
#endif
		public readonly static string defaultLang = "en.xml";

        public static List<Language> LanguageList = ReadLangList();

        public static List<Language> ReadLangList()
        {
            List<Language> languages = new List<Language>();
            if (!Directory.Exists(LangDir))
            {
                Directory.CreateDirectory(LangDir);
            }
            string[] langlist = Directory.GetFiles(LangDir, "*.xml", SearchOption.TopDirectoryOnly);
            foreach (string s in langlist)
            {
                bool IsValid = false;
                using (XmlTextReader _xml = new XmlTextReader(s))
                {
                    while (_xml.Read())
                    {
                        if (_xml.NodeType == XmlNodeType.Element & _xml.Name == "SharpieLocale")
                        {
                            IsValid = true;
                            break;
                        }
                    }

                }
                if (IsValid) languages.Add(new Language(Path.GetFileName(s), false));
            }
            languages.Sort(Language.LangEnComparison);
            return languages;
        }

        public static void ReloadLanguageList()
        {
            LanguageList = ReadLangList();
        }

        public static string String(string node)
        {
            try
            {
                return currentLang.locales[node].elementText;
            }
            catch (KeyNotFoundException)
            {
                return "<" + node + ">";
            }
        }

        public static string Tooltip(string node)
        {
            try
            {
                return currentLang.locales[node].tooltipText;
            }
            catch (KeyNotFoundException)
            {
                return "";
            }
        }


        /// <summary>
        /// Loads language file to game so it can be used to translate locales. Empty string loads default language.
        /// </summary>
        /// <param name="file">
        /// File name of the language. Don't use path separator!
        /// </param>
        public static bool LoadLang(string filename)
        {
            try
            {
                Language lang = new Language(filename, true);
                currentLang = lang;
            }
            catch (Exception ex)
            {
#if WINDOWS
                MessageBox.Show(ex.Message + " Language file " + filename + " is corrupted.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
#endif
                // TODO: dialog for Android
                return false;
            }
              return true;
        }

        public static bool LoadLang(Language language, bool LoadLocales)
        {
            try
            {
                if (LoadLocales) language.LoadLocales();
                currentLang = language;
            }
            catch (Exception ex)
            {
#if WINDOWS
                MessageBox.Show(ex.Message + " Language file " + language.filename + " is corrupted.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
#endif
                // TODO: dialog for Android
                return false;
            }
            return true;
        }

        public static void RestoreDefaultLang()
        {
#if WINDOWS
            Properties.Settings.Default.Language = defaultLang;
            Locale.LoadLang(Properties.Settings.Default.Language);
#elif ANDROID
            SharpieAndroid.Config.Nodes["Language"] = defaultLang;
            Locale.LoadLang(SharpieAndroid.Config.Nodes["Language"]);
#endif
        }

        public static string ConvertToString(string text)
        {
            string[] splitted = text.Split('{', '}');
            string glued = "";
            for (int i = 0; i < splitted.Length; i++)
            {
                if (splitted[i] == "" & splitted.Length - 1 != i)
                {
                    glued += Locale.String(splitted[i + 1]);
                    i += 1;
                }
                else
                {
                    glued += splitted[i];
                }
            }
            return glued;
        }

        public static string ConvertToTooltip(string text)
        {
            string[] splitted = text.Split('{', '}');
            string glued = "";
            for (int i = 0; i < splitted.Length; i++)
            {
                if (splitted[i] == "" & splitted.Length - 1 != i)
                {
                    glued += Locale.Tooltip(splitted[i + 1]);
                    i += 1;
                }
                else
                {
                    glued += splitted[i];
                }
            }
            return glued;
        }
    }

    public class Language
    {
        public string lang_en, lang, author;
		public string filename
		{
			get
			{
				return _filename;
			}
		}
        private string _filename;
        public Dictionary<string, LocaleNode> locales = new Dictionary<string, LocaleNode>();


        public Language(string filename, bool LoadLocale)
        {
			this._filename = Path.GetFileName(filename);
			using (XmlTextReader _xml = new XmlTextReader(Path.Combine(Locale.LangDir, filename)))
            {
                while (_xml.Read())
                {
                    if (_xml.NodeType == XmlNodeType.Element & _xml.Name == "SharpieLocale")
                    {
                        lang_en = _xml.GetAttribute(0);
                        lang = _xml.GetAttribute(1);
                        author = _xml.GetAttribute(2);
                        break;
                    }
                }
            }
            if (LoadLocale) LoadLocales();
        }

        public static Comparison<Language> LangEnComparison =
                        delegate(Language lang1, Language lang2)
                        {
                            return lang1.lang_en.CompareTo(lang2.lang_en);
                        };

        public void LoadLocales()
        {
            if (locales.Count > 0) locales.Clear();
            using (XmlTextReader _xml = new XmlTextReader(Path.Combine(Locale.LangDir, filename)))
            {
                while (_xml.Read())
                {
                    if (_xml.Depth > 0)
                    {
                        switch (_xml.NodeType)
                        {
                            case XmlNodeType.Element:
                                string tooltip, locstring;
                                if (_xml.AttributeCount > 0)
                                    tooltip = _xml.GetAttribute(0);
                                else tooltip = "";

                                locstring = _xml.ReadString();

                                locales.Add(_xml.Name, new LocaleNode(locstring, tooltip));
                                break;
                        }
                    }
                }
            }
        }

        public void UnloadLocales()
        {
            locales.Clear();
        }
    }

    public class LocaleNode
    {
        public string elementText, tooltipText;

        public LocaleNode(string elementText, string tooltipText)
        {
            this.elementText = elementText;
            this.tooltipText = tooltipText;
        }
    }
}
